﻿using Proto;
using GameServer.Core;
using Summer;
using Serilog;
using GameServer.AI;
using System;
using GameServer.Database;
using GameServer.Mgr;

namespace GameServer.Model
{
    public class Monster : Actor
    {
        public AIBase AI;
        public int type_id; //角色类型
        public int entity_id;
        public string name;
        public int level;
        public int spaceId;
        public int gold;
        public int hp;
        public int mp;
        public int attack;
        public int defense;
        public int magic;
        public int magicdefense;
        public int speed; //速度
        public int baoji;
        public int baojidefense;
        public int ViewRange=8000;
        public int MoveRange=6000;
        public int ChaseRange= 8000;

        public Vector3 moveTarget;
        public Vector3 movePosition;
        public Vector3Int initPosition;
        public Actor target;
        public bool isInstantiteWuPing=false;
        Random rand=new Random();
        private static Vector3Int Y1000 = new Vector3Int(0, 1000, 0);
        public Monster(int id,Vector3Int position, Vector3Int direction,int EntitySpeed) : base(EntityType.Monnster, id, position, direction, EntitySpeed)
        {
            state = EntityState.Idle;
            Random random = new Random();
            this.initPosition = position;
            //Scheduler.Instance.AddTask(() =>
            //{
            //    float x = this.initPosition.x + (random.NextSingle() * 10f - 5f) * 1000;
            //    float z = this.initPosition.z + (random.NextSingle() * 10f - 5f) * 1000;
            //    MoveTo(new Vector3(x, 0, z));
            //}, 15f);

            //下面这个是在做一个单独同步怪物数据客户端前使用的
            //Scheduler.Instance.AddTask(() =>{
            //    if (state != EntityState.Move&& state != EntityState.Run)
            //        return;
            //    NEntitySync es = new NEntitySync();
            //    es.Entity = this.GetData();
            //    es.Entity.Position = new NVector3()
            //    {
            //        X = (int)(movePosition.x),
            //        Y = 0,
            //        Z = (int)(movePosition.z)
            //    };
            //    es.Entity.Direction = this.Direction;
            //    es.State = state;
            //    this.Space.UpdateEntity(es);
            //},0.15f);
        }

        public void SetMonsterRoleInfo(GameEntityRoleInfoMessage gameEntityRoleInfo)
        {
            
            this.hp = gameEntityRoleInfo.Hp;
            this.level = gameEntityRoleInfo.Level;
            this.gold = (int)gameEntityRoleInfo.Gold;
            if (this.hp <= 0)
            {
                IsDead = true;
                if (!isInstantiteWuPing)
                {
                    string[] drops = DataManager.Instance.MonsterDict[gameEntityRoleInfo.EntityId].Drops.Split(';');
                    Random random = new Random();
                    int index=random.Next(drops.Length);
                    SpaceManager.Instance.GetSpace(spaceId).ChuanJianWuPing(Convert.ToInt32(drops[index]), this.Position, this.Direction);
                    isInstantiteWuPing = true;
                } 
            }
        }
        public void StopMove(bool Arrive=true)
        {
            if (Arrive)
            {
                state = EntityState.Idle;
                movePosition = moveTarget;
                NEntitySync es = new NEntitySync();
                es.Entity = this.GetData();
                es.Entity.Position = new NVector3()
                {
                    X = (int)(this.Position.x),
                    Y = 0,
                    Z = (int)(this.Position.z)
                };
                es.Entity.Direction = this.Direction;
                es.State = state;
                this.Space.UpdateEntity(es);
            }
            
        }
        public void MoveTo(Vector3 target,bool findMan=false)
        {
            if(this.state==EntityState.Idle)
            {
                if(!findMan)
                {
                    state = EntityState.Move;
                }
                else
                {
                    state = EntityState.Run;
                }
            }
            if(moveTarget!=target)
            {
                moveTarget = target;
                movePosition = new Vector3(Position.x,Position.y,Position.z);
                var dir = (moveTarget - movePosition).normalized;
                //Direction = LookRotation(dir) * Y1000;
                //Direction = new Vector3Int((int)(dir.x*1000), (int)(dir.y*1000), (int)(dir.z*1000 ));
                this.Direction = new Vector3Int(0, (int)(LookRotation(dir).y * 1000), 0);
                NEntitySync es = new NEntitySync();
                es.Entity = this.GetData();
                es.Entity.Position = new NVector3()
                {
                    X = (int)(target.x),
                    Y = 0,
                    Z = (int)(target.z )
                };
                es.Entity.Direction = Direction;
                es.State = state;
                this.Space.UpdateEntity(es);
            }
        }
        public Vector3 LookRotation(Vector3 fromDir)
        {
            float Rad2Deg = 57.29578f;
            Vector3 eulerAngles = new Vector3();
            //AngleX = arc cos(sqrt((x^2 + z^2)/(x^2+y^2+z^2)))
            eulerAngles.x = MathF.Acos(MathF.Sqrt((fromDir.x * fromDir.x + fromDir.z * fromDir.z) / (fromDir.x * fromDir.x + fromDir.y * fromDir.y + fromDir.z * fromDir.z))) * Rad2Deg;
            if (fromDir.y > 0) eulerAngles.x = 360 - eulerAngles.x;
            //AngleY = arc tan(x/z)
            eulerAngles.y = MathF.Atan2(fromDir.x, fromDir.z) * Rad2Deg;
            if (eulerAngles.y < 0) eulerAngles.y += 180;
            if (fromDir.x < 0) eulerAngles.y += 180;
            //AngleZ = 0
            eulerAngles.z = 0;
            return eulerAngles;
        }
        public override void Update()
        {
            AI?.Update();
            if (state == EntityState.Move||state==EntityState.Run)
            {
                //移动方向
                var dir = (moveTarget - movePosition).normalized;
                this.Direction = new Vector3Int(0, (int)(LookRotation(dir).y*1000), 0) ;
                //float dist = speed*0.35f * Time.deltaTime;
                //this.Direction = new Vector3Int((int)(LookRotation(dir).x * 1000), (int)(LookRotation(dir).y * 1000), (int)(LookRotation(dir).z) * 1000);
                float dist = speed * 0.35f * Time.deltaTime * 1000;
                if (Vector3.Distance(moveTarget, movePosition) < dist)
                {
                    StopMove();
                }
                else
                {
                    movePosition += dist * dir;
                }
                this.Position = new Vector3Int((int)movePosition.x, 0, (int)movePosition.z) ;
                
            }
        }
        public override void Revive()
        {
            if (SpaceManager.Instance.GetSpace(spaceId).MonsterDict.Values.Contains(this))
            {
                this.hp = DataManager.Instance.MonsterDict[type_id].hp;
                this.mp = DataManager.Instance.MonsterDict[type_id].mp;
                IsDead = false;
                isInstantiteWuPing = false;
                var resp = new SpaceMonsterEnterResponse();
                resp.SpaceId = spaceId; //场景ID
                resp.EntityList.Add(this.GetData());
                NMonster nMonster = new NMonster()
                {
                    TypeId = this.type_id,
                    Name = this.name,
                    EntityId = this.entity_id,
                    Level = this.level,
                    SpaceId = spaceId,
                    Gold = this.gold,
                    Hp = this.hp,
                    Mp = this.mp,
                    Attack = this.attack,
                    Defense = this.defense,
                    Magic = this.magic,
                    Magicdefense = this.magicdefense,
                    Speed = this.speed,
                    MonsterInitPos = this.initPosition,
                    Baoji = this.baoji,
                    Baojidefense = this.baojidefense,
                };
                resp.NNMonsterList.Add(nMonster);
                foreach (var kv in SpaceManager.Instance.GetSpace(spaceId).CharacterDict)
                {
                    kv.Value.conn.Send(resp);
                }
            }
            
        }
        //public Vector3 RandomPointWithBirth(float range)
        //{
        //    float x = this.initPosition.x + (rand.NextSingle() * 10f - 5f) * 1000;
        //    float z = this.initPosition.z + (rand.NextSingle() * 10f - 5f) * 1000;
        //    //float x =rand.NextSingle()*2f-1f;
        //    //float z = rand.NextSingle() * 2f - 1f;
        //    Vector3 dir = new Vector3(x, 0, z).normalized;
        //    return initPosition+dir * range*rand.NextSingle();
        //}
    }
}
